home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / commands / make / make.c < prev    next >
C/C++ Source or Header  |  1990-07-15  |  17KB  |  714 lines

  1. /*************************************************************************
  2.  *
  3.  *  m a k e :   m a k e . c
  4.  *
  5.  *  Do the actual making for make plus system dependent stuff
  6.  *========================================================================
  7.  * Edition history
  8.  *
  9.  *  #    Date                         Comments                       By
  10.  * --- -------- ---------------------------------------------------- ---
  11.  *   1    ??                                                         ??
  12.  *   2 01.07.89 $<,$* bugs fixed                                     RAL
  13.  *   3 23.08.89 (time_t)time((time_t*)0) bug fixed, N_EXISTS added   RAL
  14.  *   4 30.08.89 leading sp. in cmd. output eliminated, indention ch. PSH,RAL
  15.  *   5 03.09.89 :: time fixed, error output -> stderr, N_ERROR intr.
  16.  *              fixed LZ elimintaed                                  RAL
  17.  *   6 07.09.89 implmacro, DF macros,debug stuff added               RAL
  18.  *   7 09.09.89 tos support added                                    PHH,RAL
  19.  *   8 17.09.89 make1 arg. fixed, N_EXEC introduced                  RAL
  20.  * ------------ Version 2.0 released ------------------------------- RAL
  21.  *
  22.  *************************************************************************/
  23.  
  24. #include "h.h"
  25.  
  26. static bool  execflag;
  27.  
  28. /*
  29.  *    Exec a shell that returns exit status correctly (/bin/esh).
  30.  *    The standard EON shell returns the process number of the last
  31.  *    async command, used by the debugger (ugg).
  32.  *    [exec on eon is like a fork+exec on unix]
  33.  */
  34. int dosh(string, shell)
  35. char *string;
  36. char *shell;
  37. {
  38.   int number;
  39.  
  40. #ifdef unix
  41.   return system(string);
  42. #endif
  43. #ifdef tos
  44.   return Tosexec(string);
  45. #endif
  46. #ifdef eon
  47.   return ((number = execl(shell, shell,"-c", string, 0)) == -1) ?
  48.     -1:    /* couldn't start the shell */
  49.     wait(number);    /* return its exit status */
  50. #endif
  51. #ifdef os9
  52.   int    status, pid;
  53.  
  54.   strcat(string, "\n");
  55.   if ((number = os9fork(shell, strlen(string), string, 0, 0, 0)) == -1)
  56.     return -1;        /* Couldn't start a shell */
  57.   do {
  58.     if ((pid = wait(&status)) == -1)
  59.         return -1;    /* child already died!?!? */
  60.   } while (pid != number);
  61.  
  62.   return status;
  63. #endif
  64. }
  65.  
  66.  
  67. /*
  68.  *    Do commands to make a target
  69.  */
  70. void docmds1(np, lp)
  71. struct name *np;
  72. struct line *lp;
  73. {
  74.   register char       *q;
  75.   register char       *p;
  76.   register struct cmd *cp;
  77.   bool                 ssilent;
  78.   bool                 signore;
  79.   int                  estat;
  80.   char                *shell;
  81.  
  82.  
  83.   if (*(shell = getmacro("SHELL")) == '\0')
  84. #ifdef eon
  85.     shell = ":bin/esh";
  86. #endif
  87. #ifdef unix
  88.     shell = "/bin/sh";
  89. #endif
  90. #ifdef os9
  91.     shell = "shell";
  92. #endif
  93. #ifdef tos
  94.     shell = "DESKTOP";      /* TOS has no shell */
  95. #endif
  96.  
  97.   for (cp = lp->l_cmd; cp; cp = cp->c_next) {
  98.     execflag = TRUE;
  99.     strcpy(str1, cp->c_cmd);
  100.     expmake = FALSE;
  101.     expand(&str1s);
  102.     q = str1;
  103.     ssilent = silent;
  104.     signore = ignore;
  105.     while ((*q == '@') || (*q == '-')) {
  106.         if (*q == '@')       /*  Specific silent  */
  107.             ssilent = TRUE;
  108.         else           /*  Specific ignore  */
  109.             signore = TRUE;
  110.         q++;           /*  Not part of the command  */
  111.     }
  112.  
  113.     for (p=q; *p; p++) {
  114.         if (*p == '\n' && p[1] != '\0') {
  115.             *p = ' ';
  116.             if (!ssilent)
  117.                 fputs("\\\n", stdout);
  118.         }
  119.         else if (!ssilent)
  120.             putchar(*p);
  121.     }
  122.     if (!ssilent)
  123.         printf("\n");
  124.  
  125.     if (domake || expmake) {    /*  Get the shell to execute it  */
  126.         if ((estat = dosh(q, shell)) != 0) {
  127.             if (estat == -1)
  128.             fatal("Couldn't execute %s", shell,0);
  129.             else if (signore)
  130.             printf("%s: Error code %d (Ignored)\n", myname, estat);
  131.             else {
  132.             fprintf(stderr,"%s: Error code %d\n", myname, estat);
  133.             if (!(np->n_flag & N_PREC))
  134.                 if (unlink(np->n_name) == 0)
  135.                 fprintf(stderr,"%s: '%s' removed.\n", myname, np->n_name);
  136.             if (!conterr) exit(estat);
  137.             np->n_flag |= N_ERROR;
  138.             return;
  139.             }
  140.         }
  141.     }
  142.   }
  143. }
  144.  
  145.  
  146. void docmds(np)
  147. struct name *np;
  148. {
  149.   register struct line *lp;
  150.  
  151.   for (lp = np->n_line; lp; lp = lp->l_next)
  152.     docmds1(np, lp);
  153. }
  154.  
  155. #ifdef tos
  156. /*
  157.  *      execute the command submitted by make,
  158.  *      needed because TOS has no internal shell,
  159.  *      so we use Pexec to do the job
  160.  *        v 1.1 of 10/sep/89 by yeti
  161.  */
  162.  
  163. #define DELM1 ';'
  164. #define DELM2 ' '
  165. #define DELM3 ','
  166.  
  167. int Tosexec(string)
  168. char *string;
  169. {
  170.   register char *help, *help2, c;
  171.   register unsigned char l=1;
  172.   char progname[80], command[255], plain[15];
  173.   static char **envp,*env;
  174.   register int error,i;
  175.  
  176.   /* generate strange TOS environment (RAL) */
  177.   for ( i = 0, envp = environ; *envp; envp++) i += strlen(*envp) +1;
  178.   if ((env = malloc(i+1)) == (char *)0)
  179.      fatal("No memory for TOS environment",(char *)0,0);
  180.   for ( envp = environ, help = env; *envp; envp++) {
  181.      strcpy ( help, *envp);
  182.      while ( *(help++)) ;
  183.   }
  184.   *help = '\0';
  185.  
  186.   help = progname;
  187.   while((*help++=*string++) != ' '); /* progname is command name */
  188.   *--help = '\0';
  189.  
  190.   l = strlen(string);             /* build option list */
  191.   command[0] = l;                 /* TOS likes it complicated */
  192.   strcpy(&command[1],string);
  193.   if ((error = (int) Pexec(0,progname,command,env)) != -33) {
  194.     free(env);
  195.     return(error);
  196.   }
  197.  
  198.   /* could'nt find program, try to search the PATH */
  199.   if((help=strrchr(progname,'\\')) != (char *) 0)  /* just the */
  200.           strcpy(plain,++help);                     /* name     */
  201.   else if((help=strrchr(progname,'/')) != (char *) 0)
  202.           strcpy(plain,++help);
  203.   else if((help=strrchr(progname,':')) != (char *) 0)
  204.           strcpy(plain,++help);
  205.   else
  206.           strcpy(plain,progname);
  207.  
  208.   if(*(help=getmacro("PATH")) == '\0') {
  209.     free(env);
  210.     return(-33);
  211.   }
  212.   c = 1;
  213.   while(c)
  214.   {       help2 = &progname[-1];
  215.           i = 0;
  216.           while((c=*help++) != '\0' && i<80 && c != DELM1
  217.                  && c != DELM2 && c != DELM3)
  218.                   *++help2 = c, i++;
  219.           *++help2 = '\\';
  220.           strcpy(++help2,plain);
  221.           if((error=(int) Pexec(0,progname,command,env))!=-33) {
  222.                   free(env);
  223.                   return(error);
  224.           }
  225.   }
  226.   free(env);
  227.   return(-33);
  228. }
  229.  
  230.  
  231. /* (stolen from ZOO -- thanks to Rahul Dehsi)
  232. Function mstonix() accepts an MSDOS format date and time and returns
  233. a **IX format time.  No adjustment is done for timezone.
  234. */
  235.  
  236. time_t mstonix (date, time)
  237. unsigned int date, time;
  238. {
  239.    int year, month, day, hour, min, sec, daycount;
  240.    time_t longtime;
  241.    /* no. of days to beginning of month for each month */
  242.    static int dsboy[12] = { 0, 31, 59, 90, 120, 151, 181, 212,
  243.                               243, 273, 304, 334};
  244.  
  245.    if (date == 0 && time == 0)            /* special case! */
  246.       return (0L);
  247.  
  248.    /* part of following code is common to zoolist.c */
  249.    year  =  (((unsigned int) date >> 9) & 0x7f) + 1980;
  250.    month =  ((unsigned int) date >> 5) & 0x0f;
  251.    day   =  date        & 0x1f;
  252.  
  253.    hour =  ((unsigned int) time >> 11)& 0x1f;
  254.    min   =  ((unsigned int) time >> 5) & 0x3f;
  255.    sec   =  ((unsigned int) time & 0x1f) * 2;
  256.  
  257. /* DEBUG and leap year fixes thanks to Mark Alexander <uunet!amdahl!drivax!alexande>*/
  258. #ifdef DEBUG
  259.    printf ("mstonix:  year=%d  month=%d  day=%d  hour=%d  min=%d  sec=%d\n",
  260.          year, month, day, hour, min, sec);
  261. #endif
  262.    /* Calculate days since 1970/01/01 */
  263.    daycount = 365 * (year - 1970) +    /* days due to whole years */
  264.                (year - 1969) / 4 +     /* days due to leap years */
  265.                dsboy[month-1] +        /* days since beginning of this year */
  266.                day-1;                  /* days since beginning of month */
  267.  
  268.    if (year % 4 == 0 &&
  269.        year % 400 != 0 && month >= 3)  /* if this is a leap year and month */
  270.       daycount++;                      /* is March or later, add a day */
  271.  
  272.    /* Knowing the days, we can find seconds */
  273.    longtime = daycount * 24L * 60L * 60L    +
  274.           hour * 60L * 60L   +   min * 60   +    sec;
  275.     return (longtime);
  276. }
  277. #endif tos
  278.  
  279. #ifdef os9
  280. /*
  281.  *    Some stuffing around to get the modified time of a file
  282.  *    in an os9 file system
  283.  */
  284. void getmdate(fd, tbp)
  285. int fd;
  286. struct sgtbuf *tbp;
  287. {
  288.   struct registers     regs;
  289.   static struct fildes fdbuf;
  290.  
  291.  
  292.   regs.rg_a = fd;
  293.   regs.rg_b = SS_FD;
  294.   regs.rg_x = &fdbuf;
  295.   regs.rg_y = sizeof (fdbuf);
  296.  
  297.   if (_os9(I_GETSTT, ®s) == -1) {
  298.     errno = regs.rg_b & 0xff;
  299.     return -1;
  300.   }
  301.   if (tbp)
  302.   {
  303.     _strass(tbp, fdbuf.fd_date, sizeof (fdb